/**
 * 
 */
package com.siteseat.common.i18n;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.codehaus.jackson.type.TypeReference;

import com.siteseat.common.exception.InternalException;
import com.siteseat.common.json.JacksonMapper;

/**
 */
public class Labels {

  private static final TypeReference<List<Label>> JSON_MAP_TYPE = new TypeReference<List<Label>>() {};

  private List<String>                            jsonResources;

  private Map<String, Label>                      map;

  private Logger                                  log           = Logger.getLogger( Labels.class );

  /**
   * @param name
   * @return
   */
  public Label getLabel( String name ) {
    Label result = this.map.get( name );
    if( result == null ) {
      log.warn( "Unknown label '" + name + "'" );
      return Label.createEmergentLabel( name );
    }
    return result;
  }

  /**
   * @throws Exception
   */
  public void afterPropertiesSet() throws Exception {
    Map<String, Label> r = new HashMap<String, Label>();
    for( String jsonResource: getJsonResources() ) {
      for( Label lbl: loadFromJsonFile( jsonResource ) ) {
        String name = lbl.getName().toUpperCase();
        if( r.put( name, lbl ) != null ) {
          throw new InternalException( "Duplicated label '" + name + "' in resource '" + jsonResource + "'" );
        }
      }
    }
    this.map = r;
  }

  /**
   * @param jsonFileResource
   * @return
   */
  private List<Label> loadFromJsonFile( String jsonFileResource ) {
    InputStream ins = null;
    try {
      ins = Labels.class.getResourceAsStream( jsonFileResource );
      return JacksonMapper.MAPPER.readValue( ins, JSON_MAP_TYPE );
    } catch( IOException e ) {
      throw new InternalException( "Failed to read resource '" + jsonFileResource + "'", e );
    } finally {
      IOUtils.closeQuietly( ins );
    }
  }

  /**
   * @return the jsonFilePathes
   */
  public List<String> getJsonResources() {
    return jsonResources;
  }

  /**
   * @param jsonResources
   *          the jsonResources to set
   */
  public void setJsonResources( List<String> jsonResources ) {
    this.jsonResources = jsonResources;
  }

}
